using AutoMapper;
using net_work.Common;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Data.DTO.Hmw;
using net_work.Data.Entity.Hmw;
using net_work.Data.Enum.Hmw;
using net_work.IRepository.Hmw;
using net_work.IRepository.Sys;
using net_work.IService.Hmw;

namespace net_work.Service.Hmw;

public class QuestionAnswerSubmissionService(
    IMapper mapper,
    IUserContext userContext,
    IUserRepository userRepository,
    IStudentRepository studentRepository,
    IQuestionAnswerSubmissionRepository questionAnswerSubmissionRepository,
    IHomeworkQuestionRepository homeworkQuestionRepository,
    IBankQuestionRepository bankQuestionRepository,
    IBankAnswerRepository bankAnswerRepository)
    : IQuestionAnswerSubmissionService
{
    public Task<PagedResult<QuestionAnswerSubmission>> GetQuestionAnswerSubmissionsPagedAsync(PagedRequest request)
    {
        return questionAnswerSubmissionRepository.GetPagedAsync(request);
    }

    public Task<QuestionAnswerSubmission?> SelectByIdAsync(long questionAnswerSubmissionId)
    {
        return questionAnswerSubmissionRepository.GetByIdAsync(questionAnswerSubmissionId);
    }

    public async Task<long> UpdateQuestionAnswerSubmission(
        QuestionAnswerSubmissionUpdateRequest questionAnswerSubmissionUpdateRequest)
    {
        var question =
            await homeworkQuestionRepository.GetByIdAsync(questionAnswerSubmissionUpdateRequest.HomeworkQuestionId);
        if (question == null)
        {
            return -1;
        }

        // 获取学生信息
        var student = await studentRepository.GetStudentPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited,
            [new FilterCondition("UserId", FilterOperator.Equals, userContext.UserId)]));
        if (student.TotalRecords <= 0)
        {
            return -1;
        }

        var studentId = student.Data.First().Id;

        var questionAnswerSubmissionUpdateRequestBackend =
            mapper.Map<QuestionAnswerSubmissionUpdateRequestBackend>(questionAnswerSubmissionUpdateRequest);
        questionAnswerSubmissionUpdateRequestBackend.StudentId = studentId;

        return await questionAnswerSubmissionRepository.UpdateAsync(questionAnswerSubmissionUpdateRequestBackend);
    }

    public async Task<int> DeleteQuestionAnswerSubmissionByIds(List<long> ids)
    {
        return await questionAnswerSubmissionRepository.DeleteByIdsAsync(ids) ? 1 : -1;
    }

    public async Task<int> Submit(long questionAnswerSubmissionId)
    {
        var questionAnswerSubmission =
            await questionAnswerSubmissionRepository.GetByIdAsync(questionAnswerSubmissionId);
        if (questionAnswerSubmission == null)
        {
            return -1;
        }

        var homeworkQuestionId = questionAnswerSubmission.HomeworkQuestionId;
        var homeworkQuestion = await homeworkQuestionRepository.GetByIdAsync(homeworkQuestionId);
        if (homeworkQuestion == null)
        {
            return -1;
        }

        var bankQuestionId = homeworkQuestion.BankQuestionId;
        var bankQuestion = await bankQuestionRepository.GetByIdAsync(bankQuestionId);
        if (bankQuestion == null)
        {
            return -1;
        }

        var questionAnswerSubmissionUpdateRequestBackend = new QuestionAnswerSubmissionUpdateRequestBackend()
        {
            Remark = questionAnswerSubmission.Remark,
            Content = questionAnswerSubmission.Content,
            HomeworkQuestionId = homeworkQuestionId,
            StudentId = questionAnswerSubmission.StudentId,
            Id = questionAnswerSubmissionId
        };
        switch (bankQuestion.Type)
        {
            case QuestionType.SingleChoice:
            case QuestionType.MultipleChoice:
            case QuestionType.FillInTheBlank:
                var bankAnswer = await bankAnswerRepository.GetPagedAsync(new PagedRequest(1, PageSizeEnum.Unlimited, [
                    new FilterCondition("QuestionId", FilterOperator.Equals, bankQuestionId)
                ]));
                if (bankAnswer.TotalRecords <= 0)
                {
                    return -1;
                }

                questionAnswerSubmissionUpdateRequestBackend.Score =
                    bankAnswer.Data.First().Content == questionAnswerSubmission.Content ? bankQuestion.Score : 0;
                break;
            case QuestionType.FileUpload:
                break;
            case QuestionType.Subjective:
                break;
            default:
                throw new ArgumentOutOfRangeException($"QuestionType {bankQuestion.Type} is not supported.");
        }

        return await questionAnswerSubmissionRepository.SubmitAsync(questionAnswerSubmissionUpdateRequestBackend)
            ? 1
            : -1;
    }
}